package com.praveen.reminder;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.TreeMap;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Application;

public class ReminderApplication extends Application {
	public static final int REPEAT_ONCE = 0;
	public static final int REPEAT_DAILY = 1;
	public static final int REPEAT_WEEKLY = 2;
	public static final int REPEAT_MONTHLY = 3;
	public static final int REPEAT_YEARLY = 4;
	
	public static final int NO_ERROR = 0;
	public static final int TIME_ERROR = -1;
	public static final int DATE_ERROR = -2;
	
	private ArrayList<ArrayList<ReminderData>> mDataList;
	private TreeMap<Pair<Integer, String>, String> mMapDataList;
	private ArrayList<String> mGroups;
	private XMLFileManager mFileManager;
	private boolean mIsFirstStart;
	private int mMaxEntryNo;
	
	@Override
	public void onCreate() {
		mDataList = new ArrayList<ArrayList<ReminderData>>();
		mMapDataList = new TreeMap<Pair<Integer, String>, String>(new Utility.PairComparator());
		mGroups = new ArrayList<String>();
		mMaxEntryNo = 0;
		createGroups();
		File file = getApplicationContext().getFileStreamPath("appData.xml");
		if(file.exists()) {
			mIsFirstStart = false;
			mFileManager = new XMLFileManager(file);
			NodeList list = mFileManager.getDocument().getElementsByTagName("Reminder");
			for(int i = 0; i < list.getLength(); i++) {
				Element e = (Element)list.item(i);
				ReminderData data = new ReminderData();
				data.setmReminderText(e.getAttribute("Text"));
				int entryNo = Integer.parseInt(e.getAttribute("Entry"));
				data.setmEntryNo(entryNo);
				if (entryNo > mMaxEntryNo) {
					mMaxEntryNo = entryNo;
				}
				Element c = (Element)e.getFirstChild();
				while(c != null) {
					String tag = c.getTagName();
					if(tag.compareTo("Day") == 0) {
						data.setmDay(Integer.parseInt(c.getTextContent()));
					}
					else if(tag.compareTo("Month") == 0) {
						data.setmMonth(Integer.parseInt(c.getTextContent()));
					}
					else if(tag.compareTo("Year") == 0) {
						data.setmYear(Integer.parseInt(c.getTextContent()));
					}
					else if(tag.compareTo("Hour") == 0) {
						data.setmHour(Integer.parseInt(c.getTextContent()));
					}
					else if(tag.compareTo("Minute") == 0) {
						data.setmMinute(Integer.parseInt(c.getTextContent()));
					}
					else if(tag.compareTo("Options") == 0) {
						Element o = (Element)c.getFirstChild();
						data.setmRepeatFreq(Integer.parseInt(o.getTextContent()));
					}
					c = (Element)c.getNextSibling();
				}
				if (Utility.isPast(data, this) == NO_ERROR) {
					Pair<Integer, String> key = data.makeKey();
					addToMap(key, data.getmReminderText());
				}
				else {
					mFileManager.deleteDataNode(e);
				}
			}
			int pos = 0;
			for(Map.Entry<Pair<Integer, String>, String>entry : mMapDataList.entrySet()) {
				addToDataList(Utility.getReminderDataObject(entry.getKey().getFirst(), entry.getKey().getSecond(), entry.getValue()), pos);
				pos++;
			}
		}
		else {
			mFileManager = new XMLFileManager();
			mIsFirstStart = true;
		}
		super.onCreate();
	}

	public void setmMaxEntryNo(int mMaxEntryNo) {
		if (this.mMaxEntryNo < mMaxEntryNo)
			this.mMaxEntryNo = mMaxEntryNo;
	}

	public int getmMaxEntryNo() {
		return mMaxEntryNo;
	}

	public void addToDataList(ReminderData data, int pos) {
		Calendar c = Calendar.getInstance();
		GregorianCalendar cur = new GregorianCalendar(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
		GregorianCalendar gc = new GregorianCalendar (data.getmYear(), data.getmMonth() - 1, data.getmDay());
		int where = 0;
		if(cur.compareTo(gc) == 0) {
			mDataList.get(0).add(pos, data);
		}
		else {
			where += mDataList.get(0).size();
			cur.add(Calendar.DAY_OF_MONTH, 1);
			if(cur.compareTo(gc) == 0) {
				mDataList.get(1).add(pos - where, data);
			}
			else {
				where += mDataList.get(1).size();
				while(cur.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
					cur.add(Calendar.DAY_OF_WEEK, 1);
				}
				if (cur.compareTo(gc) > 0) {
					mDataList.get(2).add(pos - where, data);
				}
				else {
					where += mDataList.get(2).size();
					mDataList.get(3).add(pos - where, data);
				}
			}
		}
	}
	
	public ArrayList<ArrayList<ReminderData>> getDataList() {
		return mDataList;
	}
	
	public void addToMap(Pair<Integer, String> key, String value) {
		mMapDataList.put(key, value);
	}
	
	public Map<Pair<Integer, String>, String> getMap() {
		return mMapDataList;
	}
	
	private void createGroups() {
		mGroups.add("Today");
		mDataList.add(new ArrayList<ReminderData>());
		mGroups.add("Tomorrow");
		mDataList.add(new ArrayList<ReminderData>());
		mGroups.add("This Week");
		mDataList.add(new ArrayList<ReminderData>());
		mGroups.add("Later");
		mDataList.add(new ArrayList<ReminderData>());
	}
	
	public ArrayList<String> getGroups() {
		return mGroups;
	}
	
	public XMLFileManager getFileManager() {
		return mFileManager;
	}
	
	public boolean isFirstStart() {
		return mIsFirstStart;
	}
}
